package io.netty.client.Nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * BIO存在的问题；
 * 1，一个线程内多个阻塞,导致无法响应请求
 * 2，创建线程多，每个请求进来，得重新创建一个线程
 * 3, bio其实使用线程池，本身就能完成
 */
public class nioServerSocket {

    /**
     * 1，Bio和Nio的本质，就是阻塞和非阻塞。即使Bio+线程池，可以解决大部分的并发问题
     */
    // 1,保存客户端连接
    static List<SocketChannel> channelList = new ArrayList<>();

    public static void main(String[] args) throws IOException {

        // 1，创建NIO ServerSocketChannel,与BIO的ServerSocket类似,绑定端口号
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(8989));
        // 2,设置Socket为非阻塞模式，当accept接收连接的时候，不会阻塞等待
        serverSocketChannel.configureBlocking(false);
        System.out.println("====服务启动成功====");
        // 3,要接受连接，和处理请求
        while (true){
            // 非阻塞模式accept方法不会阻塞
            // NIO的非阻塞是操作系统实现的，底层调用了Linux的accept函数
            // 4, 接收连接请求
            SocketChannel socketChannel = serverSocketChannel.accept();
            if (socketChannel != null){  // 是否有客户端请求连接
                System.out.println("客户端连接成功");
                // 4, 设置客户端连接为非阻塞，目的是为了，在调用客户端的read方法时候，防止阻塞
                socketChannel.configureBlocking(false);
                // 将SocketChannel放入集合中
                channelList.add(socketChannel);
            }
            // 遍历连接进行数据读取
            Iterator<SocketChannel> iterator = channelList.iterator();
            while (iterator.hasNext()){
                // 5，获取客户端，遍历客户端，看是否有数据
                SocketChannel socketChannel1 = iterator.next();
                ByteBuffer buffer = ByteBuffer.allocate(24);
                // 6, 非阻塞模式，read不会阻塞
                int read = socketChannel1.read(buffer);
                if (read > 0){
                    System.out.println("接收到的客户端信息:"+new String(buffer.array()));
                }else if (read == -1){
                    iterator.remove();
                    System.out.println("客户端断开连接");
                }
            }
        }
    }
}
